/**
 * LogBuilder
 *
 * @author Chris Pratt
 *
 * 10/23/2007
 */
package com.anodyzed.onyx.log;

import com.anodyzed.onyx.log.sysout.SysOutLogFactory;

/**
 * Java 5 Log4j Facade - Allows using format strings and variable argument lists
 * to build log messages efficiently.
 *
 * Since there is no up-front string processing used to construct the log
 * message, if the logger is set above the level of the log method called, it is
 * quickly and quietly ignored, with no processing.
 *
 * If, on the other hand, the log level is below the level of the log method
 * called, the format string is processed and the supplied arguments are used to
 * build the log message.
 *
 * The Log message format string is comprised of static text with interspersed
 * replacement argument placeholders.  The placeholders begin with '{' and end
 * with '}'.
 *
 * Example:
 *   <code>"Simple {0}, More Complex {1.lastname}, Even More Complex
 *   {2.address.city}, Most Complex {1.birthDate,date,yyyyMMdd}"</code>
 *
 * The simplest is just the (zero based) index of the argument used to replace
 * the placeholder.  Additionally you can add a dot separated string of bean
 * property names to access from the indexed argument. Lastly, you can use the
 * java.text.MessageFormat style comma separated format descriptors to format
 * each replacement element.
 *
 * Example:
 *   <code>log.debug("Simple {0}, More Complex {1.lastname}, Even More Complex
 *   {2.address.city}, Most Complex {1.birthDate,date,yyyyMMdd}",
 *   5, user, company);</code>
 *
 * Might write out:
 *   <code>Simple 5, More Complex Chris, Even More Complex Sacramento,
 *   Most Complex 19640123</code>
 *
 * Oh, one last thing, if the last argument is an instance of Throwable, it will
 * be passed on to Log4j's Throwable support 
 *  
 * @see com.anodyzed.onyx.text.TextFormat 
 */
public class LogBuilder {
  public static final String FQBN = LogBuilder.class.getName();

  private static LogFactory factory;

  private static String tempId = null;

  /**
   * Set the Log Factory
   *
   * @param factory The Log Factory
   */
  public static void setLogFactory (LogFactory factory) {
    LogBuilder.factory = factory;
    if(tempId != null) {
      factory.setId(tempId);
      tempId = null;
    }
  } //setLogFactory

  /**
   * Set the Mapped Diagnostic Context Identifier for the current thread
   *
   * @param id The Identifier String
   */
  public static void setId (String id) {
    if(factory != null) {
      factory.setId(id);
    } else {
      tempId = id;
    }
  } //setId

  /**
   * Set the value of a Mapped Diagnostic Context key for the current thread
   *
   * @param key The MDC Key
   * @param val The MDC Value
   */
  public static void set (String key,String val) {
    factory.set(key,val);
  } //set

  /**
   * Get the Log Object using the Call Stack to determine the appropriate Logger
   *
   * @return The Log Object
   */
  public static Log getLogger () {
    if(factory == null) {
      factory = new SysOutLogFactory();
      System.out.println("LogBuilder.setLoggerFactory not called, defaulting to SysOutLogFactory");
    }
    return factory.getLogger();
  } //getLogger

  /**
   * Get the Log Object for the supplied class
   *
   * @param clazz The Logger Class
   * @return The Log Object
   */
  public static Log getLogger (Class<?> clazz) {
    if(factory == null) {
      factory = new SysOutLogFactory();
      System.out.println("LogBuilder.setLoggerFactory not called, defaulting to SysOutLogFactory");
    }
    return factory.getLogger(clazz);
  } //getLogger

  /**
   * Get the Log Object for the supplied category name
   *
   * @param category The Category Name
   * @return The Log Object
   */
  public static Log getLogger (String category) {
    if(factory == null) {
      factory = new SysOutLogFactory();
      System.out.println("LogBuilder.setLoggerFactory not called, defaulting to SysOutLogFactory");
    }
    return factory.getLogger(category);
  } //getLogger

} //*LogBuilder
